跳至主要内容

幹訓4

YoMin Su


回想一下


身旁有沒有朋友打手遊打到走火入魔?


13 開的「天堂 2 革命」


或是拿買賣遊戲帳號當日常的朋友?


為了賺小錢,連虛擬機都拿來用了


甚至是,在一台電腦上裝多個系統?!


這一台主機裝了 7 個 Windows...

單 CPU 6 台 8K 工作站 Ref: YouTube, Bilibili


以上皆為取自網路的真實案例


今天要說的 Docker 則是在 Linux 的容器

(虛擬機的一種)


有沒有想過開 Minecraft 伺服器可以...


從這樣


變這樣


你一定會問,那兩張有差嗎?

有差,當然有差,不然幹嘛提 xD


那,差在哪?

一個需要你從官網下載檔案,自己處理所有東西 另一個只需要一條指令,便將所有東西都準備好


除了方便架伺服器外,還能做啥?

架各種服務、各種實驗環境、服務之間各自切分、etc...


那實際上該怎麼使用呢?


首先,你需要有 Docker Engine

相信你們的電腦都準備好了,畢竟,你們的環境都已經在之前的社課讓學長姐們確認過了! (如果不是用 WSL2 的,就會是 VM)


如果沒有呢?

① 將 WSL 1 升級到 WSL 2,並安裝 Docker Desktop ② 裝任一 Linux 系統到你的筆電上 <-- 推薦!!


良心建議

如果覺得之後還是會想玩 Docker 的話,建議用 ① 但若你有破釜沉舟的堅毅心態,決定非 Linux 系統不用的話,② 就給它用下去吧!


解決辦法 ①

wsl -l -v #找到你使用的Distro
wsl --set-version <Distro> 2 #將版本修改為2

記得安裝 Docker Desktop


解決辦法 ②

雖然很棒,但今天可能不太適合...


相信各位的 Docker 都應該可以使用了,無論你用哪種方法,可以上課的方法,就是好方法~


首次嘗試


Hello-World 的部分

docker run hello-world


執行畫面


指令分析

指令用途
docker一切的起頭
run執行一個 Image
hello-worldImage 的名稱

拿 Minecraft 伺服器當範例

若想開一個伺服器的話...

docker run -e EULA=TRUE -d -p 25565:25565 --name mc itzg/minecraft-server


看起來是不是超複雜,超難懂?

一臉黑人問號...嗎?


我們一個一個參數來解釋吧!


「-e」參數

用於設定環境變數

EULA=TRUE


「-d」參數

用於讓 Container 執行在背景

就在背後跑,沒啥好說的~


「-p」參數

Port 映射,將容器裡面的 Port 對到容器外面 前面是外面,後面是裡面

25565:25565


友情提醒

預設情況下,Docker 會直接操作系統的 iptables,因此會直接跨過 ufw,若你希望服務只能在 Local 存取,請在 Port 前面加上 127.0.0.1,就像範例這樣

127.0.0.1:25565:25565


--name」

幫容器取名字,方便你管理

mc


itzg/minecraft-server

就是 MC 伺服器的 Image 之一

也就 100M+人在用而已啦~


若你玩的是 Bedrock(基岩)版的話...

好像也有 Image 可以用呢!


除上述以外,「-v」參數

可以把裡面跟外面的檔案 Mapping 起來 路徑中間用「:」連接

前面是外面,後面是裡面


小測驗時間

/srv/gitlab:/etc/gitlab

哪個在內?哪個在外?


(Q1)Answer Here~

橘色在外,藍綠色在內

如果想在容器中執行指令的話

docker exec -i mc rcon-cli

指令用途
exec執行指令
-i讓介面可以互動
mcContainer 名稱
rcon-cli指令 or 功能

Dockerfile

容器映像的起承轉合


用途

別人的映像很方便,我也想自己弄一個,可以嗎?

當然可以!


教學時間

我們來包前面設計出來的網頁吧!

# Build Stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY . .
RUN apk add make g++ \
&& npm install \
&& npm run build

# Production Stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

快速解釋時間

FROM讓此映像建立在另一個映像上
WORKDIR容器內的預設工作目錄
CPOY將目錄內的檔案複製到映像中
RUN在映像中執行指令
EXPOSE開一個"門"讓外側可以 Bind 通訊埠
CMD在映像啟動後執行的指令(程式)

範例內容

嘿,就是你們前面在上前端課程時的成果啦!

記得剛剛寫好的 Dockerfile 要放在專案的根目錄喔!


Docker 很厲害,但有沒有方便執行的工具?


當然有,就是 Docker-Compose

幫你把所有設定集合起來,一次執行的好方法


首先提一下如何使用


啟動容器

docker-compose up

加上「-f」可以指定設定檔 加上「-d」可以在背景執行


停止容器

docker-compose down

若是以指定檔名的方式去啟動的話,記得一樣要指定檔名來結束


接下來來看內容大概長怎樣


範例的說


還是範例的說,多個服務


格式的部分

首先要注意的是,這是 yml 檔,也就是 YAML 格式

雖然不像 Python 那樣對空格極度敏感,但同級別的項目需要在該行前面有相同的空格數量

父項目與子項目,建議相差 2 格


實際操作時間

拿前面自己寫好的前端 Image 當範例 我們來實際寫一下 docker-compose.yml


範例內容

version: "3"

services:
front:
build: .
image: yunnet-training/frontend
ports:
- "127.0.0.1:3000:80"

特殊情況:只要啟動其中一個

若今天只需要啟動 yml 中的其中一個容器,可以透過在啟動指令的最後方加上服務名稱,即可單獨啟動

docker-compose up -d front


額外補充

前一頁所提到「加上服務名稱」的方法,基本適用於大部分 docker-compose 指令。也就是說,如果今天有單一容器需要更新或是重建,可以單獨重新 up 該容器,就可以處理好。


Image 分享


NodeJS

執行 JavaScript 的好夥伴

hub.docker.com/_/node


NGINX

反向代理 or 網頁伺服器 就靠它

hub.docker.com/_/nginx


Dockercraft

在 Minecraft 中管理你的容器的方法

github.com/docker/dockercraft


加分時間


Q2. YAML 格式有什麼特點?

  1. 對空格__,但要求__
  2. 每個項目後面都會加上__
  3. 通常父項跟子項差__個空格

(Q2)Answer Here!

  1. 對空格不敏感,但要求同階層項目前有相同數量的空白
  2. 每個項目後面都會加上冒號
  3. 通常父項跟子項差2 個空格
let score = 100;
console.log(`每格: {score}分`);

Q3. 如果不希望 Docker 啟動的服務直接對外,在給參數時該怎麼寫?


(Q3)Answer Here...

ports:
- "127.0.0.1:<Host Port>:<LXC Port>"
SCORE=250
echo "此題: $SCORE分"

Q4. 續上題,為什麼 Docker 啟動的服務會無視 ufw 建立的防火牆條件?


(Q4)Answer Here

因為 Docker Engine 會直接對系統的 iptables 進行修改,加入運作時需要的網路結構,因此 ufw 的設定才無法正確工作。

score = 300
print(f'你可以獲得{score}分!')

感謝你的聆聽